local tank = class("tank",Base)
tank.tag = "tank"
tank.aabb = true
tank.shellCD = 5
local collsize = 12
local pullbacklimit = 64
local tank_data = {
	{name = "t1",life = 1,speed = 100,fireCD = 0.5,iron = false,water = false,range = 500,bspeed = 300},
	{name = "t2",life = 2,speed = 110,fireCD = 0.3,iron = false,water = false,range = 500,bspeed = 400},
	{name = "t3",life = 2,speed = 120,fireCD = 0.2,iron = false,water = false,range = 500,bspeed = 400},
	{name = "t4",life = 3,speed = 100,fireCD = 0.2,iron = true, water = false,range = 600,bspeed = 500},
	{name = "s1",life = 1,speed = 110,fireCD = 0.4,iron = false,water = false,range = 500,bspeed = 400},
	{name = "w1",life = 1,speed = 180,fireCD = 0.4,iron = false,water = true, range = 500,bspeed = 300},
	{name = "s2",life = 2,speed = 120,fireCD = 0.3,iron = false,water = false,range = 800,bspeed = 700},
	{name = "s3",life = 4,speed = 80, fireCD = 0.2,iron = true, water = false,range = 500,bspeed = 600},
}

local initTime = 3
function tank:init(game,x,y,rot,scale,team,type,age)
    self.game = game
    self.x = x
    self.y = y
    self.ax = 8
    self.ay = 8
    self.rot = rot or 0
    self.dx = 0
    self.dy = 0
    self.tx = x
    self.ty = y
    self.trot = rot or 0
    self.team = team
    self.scale = scale or 1
    self.type = type or 1
    self.mx = x
    self.my = y
    self.tank_data = tank_data[type]
    for k,v in pairs(self.tank_data) do
        self[k] = v
    end

    self.bornTimer = age or 0
    self.inShell = false
    self.fireTimer = 0
    self.shellTimer = 0
    self.poweroffTimer = 0
    
    
    self.game.world:add(self,
        self.x-collsize/2*self.scale,
        self.y-collsize/2*self.scale,
        self.scale*collsize,self.scale*collsize)

    if not SERVER then
        self.starAnim = texture:newAnim("star")
        self.shellAnim = texture:newAnim("shell")
        self.bodyAnim = texture:newTankAnim(self.team,self.type)
        self.anim = self.starAnim
    end

    self:createData(x,y,rot,scale,team,type,age)
end


function tank:setAI(ai_string)
    self.ai = loadstring(ai_string)()
end

function tank:controlByPlayer(dt)
    local down = love.keyboard.isDown
    local ox,oy = self.x,self.y
    if not self.speedLock then
        self.dx = 0
        self.dy = 0
    end

    

    if down("w") then
        self.dx = 0
        self.dy = - self.speed*dt
        self.rot = 0
    elseif down("s") then
        self.dx = 0
        self.dy = self.speed*dt
        self.rot = 2
    end

    if down("a") then
        self.dy = 0
        self.dx = - self.speed*dt
        self.rot = 3
    elseif down("d") then
        self.dy = 0
        self.dx = self.speed*dt
        self.rot = 1
    end

    if self.game.vpad then
        self.game.vpad:control(self,dt)
    end

    if  down("space") then
        self:fire()
    end

    self.x = self.x + self.dx
    self.y = self.y + self.dy

    if net.inGame then
        if math.abs(self.tx - self.x) > pullbacklimit then
            self.x = self.x + (self.tx - self.x)/2
        end

        if math.abs(self.ty - self.y) > pullbacklimit then
            self.y = self.y + (self.ty - self.y)/2
        end
    else
        self.tx = self.x
        self.ty = self.y
        self.trot = self.rot
    end
    

    self.mx = self.x
    self.my = self.y

    local moved = not(self.x == ox and self.y == oy)

    if not SERVER then
        if moved then
            sound:play("tankmove")
            sound:stop("tankidle")
        else
            sound:play("tankidle")
            sound:stop("tankmove")
        end
    end
    return moved
end

function tank:controlByServer(dt)
    self.mx = self.x + (self.tx - self.x)/2
    self.my = self.y + (self.ty - self.y)/2
    self.x = self.mx
    self.y = self.my
    self.rot = self.trot
end

function tank:controlByAI()
    self:ai()
    self.x = self.x + self.dx
    self.y = self.y + self.dy
    self.mx = self.x
    self.my = self.y
    if self.dx~=0 or self.dy~=0 then self.dirty = true end
    if not net.inGame then
        self.tx = self.x
        self.ty = self.y
        self.trot = self.rot
    end
end

function tank:fire()
    if self.fireTimer<0 or force then
        self.fireTimer = self.fireCD
 
        local x = self.x
        local y = self.y
        if self.rot == 0 then
            y = self.y - self.scale*8
        elseif self.rot == 1 then
            x = self.x + self.scale*8
        elseif self.rot == 2 then
            y = self.y + self.scale*8
        elseif self.rot == 3 then
            x = self.x - self.scale*8
        end

        local bullet = Bullet(self.game,x,y,self.rot,self.scale,self.team,self.iron,self.range,self.bspeed,self.id)
        if net.inGame then 
            net.client:send("need_fire",bullet.data)
            bullet:setID(self.game:newLocalID())
        elseif net.server then
            self.game:setNetObj(bullet)
        else --local game
            bullet:setID(self.game:newLocalID())
            --print("local")
        end
        
    end
end



function tank.collFilter(me,other)
    if other.tag == "brick" or other.tag == "iron" 
        or other.tag == "hq" or other.tag == "tank" or other.tag == "border" then
        return bump.Response_Slide
    elseif other.tag == "water" and not me.water then
        return bump.Response_Slide
    else
        return bump.Response_Cross
    end
end

function tank:collision(cols)
    if self.destroyed then return end
    for i,col in ipairs(cols) do
        local other = col.other
        if other.tag == "ice" then
            self.speedLock = true
            --sound:play("ice")
        end
    end
    return #cols>0
end

function tank:checkColl()
    local x, y ,cols = self.game.world:move(self,
        self.x - collsize/2*self.scale,
        self.y - collsize/2*self.scale,self.collFilter)
    self.x, self.y = x + collsize/2*self.scale, 
    y + collsize/2*self.scale
    self.speedLock = false
    self:collision(cols)
    self.mx = self.x
    self.my = self.y
end

function tank:timer(dt)
    self.fireTimer = self.fireTimer - dt
    self.shellTimer =self.shellTimer - dt
    self.poweroffTimer =self.poweroffTimer - dt
    if self.shellTimer<0 then
        self.inShell = false
    end
    self.bornTimer = self.bornTimer + dt
    if self.bornTimer<initTime then
        self.inShell = true
        self.anim = self.starAnim
        self.poweroffTimer = initTime - self.bornTimer
        self.shellTimer = initTime - self.bornTimer + 2
    else
        self.anim = self.bodyAnim
    end
    if not SERVER then
        if self.bornTimer<0 then
            if not self.born then
                self.born = true
                self.anim = texture:newTankAnim(self.team,self.type)
            end
        end
    end
end

function tank:update(dt)
    if self.destroyed then return end
    self:timer(dt)
    if self == self.game.player then
        if self.poweroffTimer<0 then
            local moved = self:controlByPlayer(dt)
            if moved then
                self:checkColl()
                self:syncMove()
            end
        end
    elseif self.ai then
        if self.poweroffTimer<0 then
            self:controlByAI(dt)
            self:checkColl()
            self:syncMove()
        end
    elseif net.server then
        self:checkColl()
        self:syncMove()
    else
        self:controlByServer(dt)
        self:checkColl()
    end
end

function tank:mark()
    self.markOff = 400
    self.arrowOff = 0
end

function tank:drawMark()
    self.markOff = self.markOff - 10
    if self.markOff>0 then
       
        for i = 1,3 do
            love.graphics.setLineWidth(4-i)
            local off = self.markOff/i
            love.graphics.setColor(1, 0, 0, 1)
            love.graphics.rectangle("line", self.x-off, self.y-off, off*2, off*2)
        end
        love.graphics.setLineWidth(1)
    else
        love.graphics.setColor(1, 0, 0, 1)
        local off = math.sin(self.markOff/40)*5
        love.graphics.polygon("fill", 
            self.mx-10,self.my-30 + off,
            self.mx,self.my-20 + off,
            self.mx+10,self.my-30 + off
            )
    end
end


function tank:draw()
    love.graphics.setColor(1,1,1)
    self.anim:update(love.timer.getDelta())
    local mx,my = math.floor(self.mx),math.floor(self.my)
    self.anim:draw(mx,my,self.rot*math.pi/2,self.scale,self.scale,self.ax,self.ay)
    if __TESTING then
        love.graphics.setColor(1,0,0,0.3)
        self.anim:draw(self.tx,self.ty,self.trot*math.pi/2,self.scale,self.scale,self.ax,self.ay)
    end
    if self.netID then
        local f = love.graphics.getFont()
        love.graphics.setFont(texture.tinyfont)
        love.graphics.setColor(1,1,1)
        love.graphics.printf(self.netID.." : "..self.game.players[self.netID].score, self.mx-100, self.my-30, 200,"center")
        love.graphics.setFont(f)
    end
    if self.inShell then
        self.shellAnim:update(love.timer.getDelta())
        local rnd = math.random()
        if rnd<0.33 then
            love.graphics.setColor(0,0,1)
        elseif rnd<0.66 then 
            love.graphics.setColor(1,0,0)
        else
            love.graphics.setColor(1,1,1)
        end
        self.shellAnim:draw(mx,my,0,self.scale,self.scale,self.ax,self.ay)
    end
end

function tank:changeType(t)
    self.type = t
    self.tank_data = tank_data[t]
    for k,v in pairs(self.tank_data) do
        self[k] = v
    end
    if not SERVER then
        self.bodyAnim = texture:newTankAnim(self.team,self.type)
    end
    if net.server then
        net:sendToRoom(self.game.room,"change_type",{id = self.id,t = t})
    end
end

function tank:poweroff(time)
    self.poweroffTimer = time or 5
    if net.server then
        net:sendToRoom(self.game.room,"power_off",{id = self.id,t = time})
    end
end

function tank:takeShell(time)
    self.shellTimer = time or self.shellCD
    self.inShell = true
    if net.server then 
        net:sendToRoom(self.game.room,"take_shell",{id = self.id,t = time} )
    end
end

function tank:damage(bywho)
    if self.inShell then return end
    self.life = self.life - 1
    if self.life == 0 then
        self.game:onKill(bywho,self)
        self:destroy()
    end
    if net.server then
        net:sendToRoom(self.game.room,"damage",{id = self.id})
    end
end


function tank:destroy()
    Base.destroy(self)
    Ding(self.game,self.x,self.y,self.scale)
    if not SERVER then
        sound:play("destroy")
        sound:stop("tankidle")
        sound:stop("tankmove")
    end
end
return tank